#lang rosetta-racket


(provide slab
         handrail
         guard
         balcony)


(define (coords-fn c fn x0 x1 dx)
  (if (> x0 x1)
      (list)
      (cons
       (+xy c x0 (fn x0))
       (coords-fn c fn (+ x0 dx) x1 dx))))

(define (slab c fn x0 x1 dx ly lz)
  (let ((pontos (coords-fn (+xy c (- x0) (- ly)) fn x0 x1 dx)))
    (let ((p0 (first pontos))
          (p1 (last pontos)))
      (extrude
       lz
       uz
       (surface
        (join
         (spline pontos)
         (line p0 c (+x c (- x1 x0)) p1)))))))

(define (handrail c fn x0 x1 dx ly l h)
  (sweep
   (spline (coords-fn (+xy c (- x0) (- ly)) fn x0 x1 dx))
   (surface (line-closed u0 (y l) (yz l h) (z h)))))

(define (bobs c fn x0 x1 dx ly h r)
  (for/list ((ponto (coords-fn (+xy c (- x0) (- ly)) fn x0 x1 dx)))
    (cylinder ponto r (+z ponto h))))

(define (guard c fn x0 x1 dx ly guard-h handrail-l handrail-h bobs-d)
  (list
   (handrail (+z c guard-h) fn x0 x1 bobs-d ly handrail-l handrail-h)
   (bobs c fn x0 x1 bobs-d ly guard-h (/2 handrail-l))))

(define (balcony c fn x0 x1 dx ly slab-h guard-h handrail-l handrail-h bobs-d)
  (list
   (slab c fn x0 x1 bobs-d ly slab-h)
   (guard (+xyz c 0 handrail-l slab-h)
           fn x0 x1 dx ly guard-h handrail-l handrail-h bobs-d)))